import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:online_bookstore/constants/app_constants.dart';
import 'package:online_bookstore/models/user.dart';
import 'package:online_bookstore/models/cart_item.dart';

class StorageService {
  static final StorageService _instance = StorageService._internal();
  factory StorageService() => _instance;
  StorageService._internal();

  SharedPreferences? _prefs;

  Future<void> initialize() async {
    _prefs = await SharedPreferences.getInstance();
  }

  // User data
  Future<void> saveUser(User user) async {
    if (_prefs == null) await initialize();
    await _prefs!.setString(AppConstants.userDataKey, jsonEncode(user.toJson()));
  }

  Future<User?> getUser() async {
    if (_prefs == null) await initialize();
    final userJson = _prefs!.getString(AppConstants.userDataKey);
    if (userJson != null) {
      return User.fromJson(jsonDecode(userJson));
    }
    return null;
  }

  Future<void> clearUser() async {
    if (_prefs == null) await initialize();
    await _prefs!.remove(AppConstants.userDataKey);
  }

  // Auth token
  Future<void> saveAuthToken(String token) async {
    if (_prefs == null) await initialize();
    await _prefs!.setString(AppConstants.userTokenKey, token);
  }

  Future<String?> getAuthToken() async {
    if (_prefs == null) await initialize();
    return _prefs!.getString(AppConstants.userTokenKey);
  }

  Future<void> clearAuthToken() async {
    if (_prefs == null) await initialize();
    await _prefs!.remove(AppConstants.userTokenKey);
  }

  // Cart data
  Future<void> saveCart(List<CartItem> cartItems) async {
    if (_prefs == null) await initialize();
    final cartJson = cartItems.map((item) => item.toJson()).toList();
    await _prefs!.setString(AppConstants.cartDataKey, jsonEncode(cartJson));
  }

  Future<List<CartItem>> getCart() async {
    if (_prefs == null) await initialize();
    final cartJson = _prefs!.getString(AppConstants.cartDataKey);
    if (cartJson != null) {
      final List<dynamic> cartList = jsonDecode(cartJson);
      return cartList.map((json) => CartItem.fromJson(json)).toList();
    }
    return [];
  }

  Future<void> clearCart() async {
    if (_prefs == null) await initialize();
    await _prefs!.remove(AppConstants.cartDataKey);
  }

  // Theme mode
  Future<void> saveThemeMode(String themeMode) async {
    if (_prefs == null) await initialize();
    await _prefs!.setString(AppConstants.themeKey, themeMode);
  }

  Future<String?> getThemeMode() async {
    if (_prefs == null) await initialize();
    return _prefs!.getString(AppConstants.themeKey);
  }

  // Language
  Future<void> saveLanguage(String languageCode) async {
    if (_prefs == null) await initialize();
    await _prefs!.setString(AppConstants.languageKey, languageCode);
  }

  Future<String?> getLanguage() async {
    if (_prefs == null) await initialize();
    return _prefs!.getString(AppConstants.languageKey);
  }

  // Generic methods
  Future<void> saveString(String key, String value) async {
    if (_prefs == null) await initialize();
    await _prefs!.setString(key, value);
  }

  Future<String?> getString(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.getString(key);
  }

  Future<void> saveBool(String key, bool value) async {
    if (_prefs == null) await initialize();
    await _prefs!.setBool(key, value);
  }

  Future<bool?> getBool(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.getBool(key);
  }

  Future<void> saveInt(String key, int value) async {
    if (_prefs == null) await initialize();
    await _prefs!.setInt(key, value);
  }

  Future<int?> getInt(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.getInt(key);
  }

  Future<void> saveDouble(String key, double value) async {
    if (_prefs == null) await initialize();
    await _prefs!.setDouble(key, value);
  }

  Future<double?> getDouble(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.getDouble(key);
  }

  Future<void> saveStringList(String key, List<String> value) async {
    if (_prefs == null) await initialize();
    await _prefs!.setStringList(key, value);
  }

  Future<List<String>?> getStringList(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.getStringList(key);
  }

  Future<void> remove(String key) async {
    if (_prefs == null) await initialize();
    await _prefs!.remove(key);
  }

  Future<void> clear() async {
    if (_prefs == null) await initialize();
    await _prefs!.clear();
  }

  Future<bool> containsKey(String key) async {
    if (_prefs == null) await initialize();
    return _prefs!.containsKey(key);
  }

  Future<Set<String>> getKeys() async {
    if (_prefs == null) await initialize();
    return _prefs!.getKeys();
  }
}
